package com.tk.exam.service.impl;

import com.github.pagehelper.PageInfo;
import com.tk.exam.dao.StuScoreDao;
import com.tk.exam.domain.TkExamInfo;
import com.tk.exam.domain.TkStudentScore;
import com.tk.exam.domain.TkStudentScoreExample;
import com.tk.exam.domain.TkStudentScoreExtExample;
import com.tk.exam.exception.ApiException;
import com.tk.exam.mapper.StuScoreExtMapper;
import com.tk.exam.mapper.TkExamInfoExtMapper;
import com.tk.exam.mapper.TkStudentScoreMapper;
import com.tk.exam.service.StuScoreService;
import com.tk.exam.vo.exam.SearchExamListRespVo;
import com.tk.exam.vo.score.SearchStuScoreListResp;
import com.tk.exam.vo.score.TkStudentScoreExt;
import com.tk.exam.vo.score.UpStuScoreReq;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.stream.Collectors;

@Service
public class StuScoreServiceImpl implements StuScoreService {
    private static final String FILENAME = "考试成绩.xls";
    private static final String SHEETNAME = "考试成绩";
    @Autowired
    private StuScoreDao stuScoreDao;
    @Autowired
    private TkStudentScoreMapper scoreMapper;
    @Autowired
    private StuScoreExtMapper stuScoreExtMapper;

    @Autowired
    private TkExamInfoExtMapper tkExamInfoExtMapper;

    @Override
    public PageInfo<SearchStuScoreListResp> searchStudentScoreListByPage(int examId) {
        return stuScoreDao.searchStuScoreListByPageWithPage(examId);
    }

    @Override
    public void upStuOffLineScore(List<UpStuScoreReq> reqs) {

        //todo:研究一下example能不能自己写一个
        List<TkStudentScore> scores=stuScoreExtMapper.batchSelectById(reqs);
        Map<Integer,Double> idOnLineScoreMaps=scores.parallelStream().collect(Collectors.toConcurrentMap(TkStudentScore::getId,TkStudentScore::getOnlineSocre));
        Vector<TkStudentScore> records=new Vector();
        reqs.parallelStream().forEach(
                req -> {
                    TkStudentScoreExt record=new TkStudentScoreExt(req,idOnLineScoreMaps.get(req.getScoreId()));
                    records.add(record);
                }
        );
        stuScoreExtMapper.batchUpdateByPrimaryKeySelective(records);
    }

    @Override
    public int exportStudentScore(String examId) {
        //查询考生成绩列表
        List<SearchStuScoreListResp> scoreList = stuScoreExtMapper.searchStuScoreListByPage(Integer.parseInt(examId));
        TkExamInfo e = tkExamInfoExtMapper.selectByPrimaryKey(Integer.parseInt(examId));
        List<SearchExamListRespVo> vos = tkExamInfoExtMapper.selectById(examId);
        if(CollectionUtils.isEmpty(vos)){
            throw ApiException.of("该考试不存在");
        }
        SearchExamListRespVo examVo = vos.get(0);
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = attributes.getResponse();
        HttpServletRequest request = attributes.getRequest();
        exportScore(request,response,scoreList,examVo,FILENAME,SHEETNAME);
        return 0;


    }


    public int exportScore(HttpServletRequest request,HttpServletResponse response, List<SearchStuScoreListResp> scoreList,SearchExamListRespVo examVo, String fileName, String sheetName) {
        int j= 0;

        HSSFWorkbook book = new HSSFWorkbook();
        HSSFSheet sheet = book.createSheet(sheetName);
        // 声明一行
        HSSFRow row = sheet.createRow(0);
        row.createCell(0).setCellValue("考试名称");
        row.createCell(1).setCellValue("考试地点");
        row.createCell(2).setCellValue("考试时间");
        row.createCell(3).setCellValue("考试时长（分钟）");
        row.createCell(4).setCellValue("选用试卷");
        row.createCell(5).setCellValue("考试班级");
        row = sheet.createRow(1);
        row.createCell(0).setCellValue(examVo.getExamName());
        row.createCell(1).setCellValue(examVo.getExamLocation());
        row.createCell(2).setCellValue(examVo.getExTime());
        row.createCell(3).setCellValue(examVo.getExamTotalTime());
        row.createCell(4).setCellValue(examVo.getPaperName());
        row.createCell(5).setCellValue(examVo.getClassName());
        row = sheet.createRow(3);
        row.createCell(0).setCellValue("考生姓名");
        row.createCell(1).setCellValue("手机号");
        row.createCell(2).setCellValue("所属单位");
        row.createCell(3).setCellValue("机考成绩");
        row.createCell(4).setCellValue("线下考试成绩");
        row.createCell(5).setCellValue("考试总成绩");
        int index = 0;//记录额外创建的sheet数量
        for (int i = 0; i < scoreList.size(); i++) {
            if ((i + 1) % 65533 == 0) {
                sheet = book.createSheet(sheetName + index);
                row = sheet.createRow(0);
                row.createCell(0).setCellValue("考生姓名");
                row.createCell(1).setCellValue("手机号");
                row.createCell(2).setCellValue("所属单位");
                row.createCell(3).setCellValue("机考成绩");
                row.createCell(4).setCellValue("线下考试成绩");
                row.createCell(5).setCellValue("考试总成绩");
                index++;
                row = sheet.createRow((i + 2) - (index * 65535));
            }else {
                row = sheet.createRow((i + 4) - (index * 65533));
            }
            // 第四步，创建单元格，并设置值
            row.createCell((short) 0).setCellValue(scoreList.get(i).getStudentName());
            row.createCell((short) 1).setCellValue(scoreList.get(i).getPhoneNo());
            row.createCell((short) 2).setCellValue(scoreList.get(i).getDepartment());
            row.createCell((short) 3).setCellValue(scoreList.get(i).getOnlineSocre()+"");
            row.createCell((short) 4).setCellValue(scoreList.get(i).getOfflineSocre()+"");
            row.createCell((short) 5).setCellValue(scoreList.get(i).getTotalSocre()+"");
        }

        //响应到客户端
        String agent=request.getHeader("User-Agent").toLowerCase();
        setResponseHeader(response, fileName,agent);
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            book.write(os);
            os.flush();
            os.close();
            j=1;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return j;
    }

    //发送响应流方法
    public void setResponseHeader(HttpServletResponse response, String fileName, String agent) {
        try {

            response.setContentType("application/vnd.ms-excel");// // 指定文件的保存类型。
            response.setHeader("content-Disposition", "attachment;filename="+ encodeDownloadFilename(fileName,agent));
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");

        } catch (Exception ex) {
            ex.printStackTrace();

        }
    }

    /**
     * 下载文件时，针对不同浏览器，进行附件名的编码
     *
     * @param filename 下载文件名
     * @param agent 客户端浏览器
     * @return 编码后的下载附件名
     * @throws IOException
     */
    public static String encodeDownloadFilename(String filename, String agent)
            throws IOException {
        if (agent.contains("firefox")) { // 火狐浏览器
            filename = "=?UTF-8?B?"
                    + new BASE64Encoder().encode(filename.getBytes("utf-8"))
                    + "?=";
            filename = filename.replaceAll("\r\n", "");
        } else { // IE及其他浏览器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+"," ");
        }
        return filename;
    }

}
